package com.qpcy.utils;

import cn.hutool.core.lang.UUID;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.qpcy.config.OSSConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component
public class OssUtils {

    @Autowired
    private OSSConfig ossConfig;

    public List<String> upload(List<MultipartFile> files) throws IOException {
        // 获取配置信息
        String bucketName = ossConfig.getBucketName();
        String endPoint = ossConfig.getEndPoint();
        String accessKeyId = ossConfig.getAccessKeyId();
        String accessKeySecret = ossConfig.getAccessKeySecret();

        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
        List<String> urls = new ArrayList<>();
        try {
            for (MultipartFile file : files) {
                // 获取文件原始名称
                String originalFilename = file.getOriginalFilename();
                String suffix = Objects.requireNonNull(originalFilename)
                        .substring(originalFilename.lastIndexOf("."));

                // 生成UUID作为文件名，保证唯一性
                String fileName = UUID.fastUUID().toString().replace("-", "").substring(0, 16) + suffix;

                // 以上传日期作为文件夹名称
                LocalDate today = LocalDate.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String day = today.format(formatter);
                fileName = day + "/" + fileName;

                // 判断文件大小，如果大于5MB，使用分片上传
                if (file.getSize() > 5 * 1024 * 1024) {
                    uploadInParts(ossClient, bucketName, fileName, file);
                } else {
                    // 小文件直接上传
                    ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(file.getBytes()));
                }
                urls.add("https://" + bucketName + "." + "oss-cn-hangzhou.aliyuncs.com" + "/" + fileName);
            }
            // 返回文件的OSS URL
            return urls;
        } finally {
            // 关闭OSSClient
            ossClient.shutdown();
        }
    }

    private void uploadInParts(OSS ossClient, String bucketName, String fileName, MultipartFile file) throws IOException {
        // 初始化分片上传
        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, fileName);
        InitiateMultipartUploadResult uploadResult = ossClient.initiateMultipartUpload(request);
        String uploadId = uploadResult.getUploadId();

        // 分片大小（例如 5MB）
        int partSize = 5 * 1024 * 1024;
        List<PartETag> partETags = new ArrayList<>();

        try (InputStream inputStream = file.getInputStream()) {
            int partNumber = 1;
            byte[] buffer = new byte[partSize];
            int bytesRead;

            while ((bytesRead = inputStream.read(buffer)) > 0) {
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(fileName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setPartNumber(partNumber);
                uploadPartRequest.setPartSize(bytesRead);
                uploadPartRequest.setInputStream(new ByteArrayInputStream(buffer, 0, bytesRead));

                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                partETags.add(uploadPartResult.getPartETag());
                partNumber++;
            }
        }

        // 完成分片上传
        CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(
                bucketName, fileName, uploadId, partETags);
        ossClient.completeMultipartUpload(completeRequest);

    }

}
